﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO.Ports;
using ZedGraph;
using System.IO;

namespace LED_Tester
{
    public partial class frmR7 : Form
    {
        public frmR7()
        {
            InitializeComponent();
        }

        #region 电源变量

        private ClassSourceMeter classSourceMeter;
        private int sourceMode;
        private SerialPort sptSource;
        private bool sourceIsJoin;
        private double voltSet;
        private double currSet;
        private double voltCheck;
        private double currCheck;

        public ClassSourceMeter Class_SourceMeter
        {
            get { return classSourceMeter; }
            set { classSourceMeter = value; }
        }
        public int SourceMode
        {
            get { return sourceMode; }
            set { sourceMode = value; }
        }
        public SerialPort SPTSource
        {
            get { return sptSource; }
            set { sptSource = value; }
        }
        public bool SourceIsJoin
        {
            get { return sourceIsJoin; }
            set { sourceIsJoin = value; }
        }
        public double VoltSet
        {
            get { return voltSet; }
            set { voltSet = value; }
        }
        public double CurrSet
        {
            get { return currSet; }
            set { currSet = value; }
        }

        #endregion

        #region 光谱仪变量

        private ClassSpectralMeter classSpectralMeter;
        private bool spectralIsJoin;
        private ClassSpectralMeter.Param param;
        private ClassSpectralMeter.Result result;

        public ClassSpectralMeter Class_SpectralMeter
        {
            get { return classSpectralMeter; }
            set { classSpectralMeter = value; }
        }
        public bool SpectralIsJoin
        {
            get { return spectralIsJoin; }
            set { spectralIsJoin = value; }
        }
        public ClassSpectralMeter.Param Param
        {
            get { return param; }
            set { param = value; }
        }
        public ClassSpectralMeter.Result Result
        {
            get { return result; }
            set { result = value; }
        }

        #endregion

        #region 变量声明

        private string[][] dataCIE;
        private PointPairList pplCIE1931 = new PointPairList();
        private LineItem litCIE1931;

        private string[][] dataSDCM;
        private int[] ANSITc;// 用于保存ANSI色温数据
        private int[] IECTc;// 用于保存IEC色温数据
        private int ANSIIndex;// 用于保存ANSI数量
        private int IECIndex;// 用于保存IEC数量
        private double[][] ANSIParam;// 用于保存ANSI计算SDCM参数
        private double[][] IECParam;//用于保存IEC计算SDCM参数
        private PointPairList pplSDCM = new PointPairList();// 用于打点
        private LineItem litSDCM;

        private int sdcmIndex = 1;
        private int rankLo = 1;
        private int rankHi = 10;

        public int SDCMIndex
        {
            get { return sdcmIndex; }
            set { sdcmIndex = value; }
        }
        public int RankLo
        {
            get { return rankLo; }
            set { rankLo = value; }
        }
        public int RankHi
        {
            get { return rankHi; }
            set { rankHi = value; }
        }

        #endregion

        #region 其它变量

        private int index;
        private bool isMeasure = false;
        private bool isR7 = true;
        private double[] secondParam;
        private string[] information;

        private Thread threadMeasure;

        private delegate void dlgShowButton();
        private delegate void dlgDisplay();

        public double[] SecondParam
        {
            get { return secondParam; }
            set { secondParam = value; }
        }
        public string[] Information
        {
            get { return information; }
            set { information = value; }
        }

        #endregion

        #region 功能函数

        private void readCIE(string fileName)
        {
            if (!File.Exists(fileName))
            {
                return;
            }

            FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

            if (fileStream == null)
            {
                return;
            }

            StreamReader streamReader = new StreamReader(fileStream);

            int index = 0;
            dataCIE = new string[80][];

            try
            {
                while (!streamReader.EndOfStream)
                {
                    string str = "";
                    str = streamReader.ReadLine();
                    string[] temp = new string[2];
                    temp = str.Split("	".ToCharArray());
                    dataCIE[index] = temp;
                    index++;
                }
            }
            catch { }
            finally
            {
                streamReader.Close();
                fileStream.Close();
            }
        }

        private void drawCIE(ZedGraphControl zed, string fileName)
        {
            zed.GraphPane.CurveList.Clear();

            zed.GraphPane.Chart.Fill = new ZedGraph.Fill(Color.White);
            zed.IsShowContextMenu = false; // 设置右键功能选项
            zed.IsShowPointValues = true;
            zed.PointValueFormat = "#0.0000";
            zed.GraphPane.Title.Text = "";

            zed.GraphPane.XAxis.Title.Text = "x";
            zed.GraphPane.XAxis.MajorGrid.IsVisible = true;
            zed.GraphPane.XAxis.Scale.Max = 0.8f;
            zed.GraphPane.XAxis.MajorGrid.PenWidth = 1f;

            zed.GraphPane.YAxis.Title.Text = "y";
            zed.GraphPane.YAxis.MajorGrid.IsVisible = true;
            zed.GraphPane.YAxis.Scale.Max = 0.9f;
            zed.GraphPane.YAxis.MajorGrid.PenWidth = 1f;

            readCIE(fileName);

            PointPairList pplList = new PointPairList();
            for (int i = 0; i < dataCIE.Length; i++)
            {
                double x = double.Parse(dataCIE[i][0].ToString());
                double y = double.Parse(dataCIE[i][1].ToString());
                pplList.Add(x, y);
            }
            pplList.Add(double.Parse(dataCIE[0][0].ToString()), double.Parse(dataCIE[0][1].ToString()));
            pplList.Add(double.Parse(dataCIE[79][0].ToString()), double.Parse(dataCIE[79][1].ToString()));

            LineItem litLine = zed.GraphPane.AddCurve("", pplList, Color.Blue, SymbolType.None);

            zed.AxisChange();
            zed.Refresh();
        }

        private void pointCIE(double x, double y)
        {
            pplCIE1931.Clear();

            pplCIE1931.Add(x, y);

            litCIE1931 = zedCIE.GraphPane.AddCurve("", pplCIE1931, Color.Red, SymbolType.XCross);

            litCIE1931.Line.IsVisible = false;

            zedCIE.Refresh();
        }

        private void readSDCM(string fileName)
        {
            if (!File.Exists(fileName))
            {
                return;
            }

            FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

            if (fileStream == null)
            {
                return;
            }

            StreamReader streamReader = new StreamReader(fileStream);

            int i = 0;
            dataSDCM = new string[12][];
            try
            {
                while (!streamReader.EndOfStream)
                {
                    string str = "";
                    str = streamReader.ReadLine();
                    string[] data = new string[17];
                    data = str.Split(" ".ToCharArray());
                    dataSDCM[i] = data;//每一行所有数据
                    i++;
                }
            }
            catch { }
            finally
            {
                streamReader.Close();
                fileStream.Close();
            }

            ANSITc = new int[6];//色温
            IECTc = new int[6];//色温
            ANSIParam = new double[6][];//色温对应的系数
            IECParam = new double[6][];//色温对应的系数
            ANSIIndex = 0;//索引
            IECIndex = 0;//索引
            double[] temp;
            for (int j = 0; j < dataSDCM.Length; j++)
            {
                if (dataSDCM[j][0].Substring(0, 4) == "ANSI")
                {
                    temp = new double[10];
                    ANSITc[ANSIIndex] = int.Parse(dataSDCM[j][0].Substring(5, 4));
                    temp[0] = double.Parse(dataSDCM[j][9]);//x1
                    temp[1] = double.Parse(dataSDCM[j][10]);//y1
                    temp[2] = double.Parse(dataSDCM[j][3]);//g11
                    temp[3] = double.Parse(dataSDCM[j][4]);//g12
                    temp[4] = double.Parse(dataSDCM[j][5]);//g13
                    temp[5] = double.Parse(dataSDCM[j][6]);//angle
                    temp[6] = double.Parse(dataSDCM[j][1]);//x
                    temp[7] = double.Parse(dataSDCM[j][2]);//y
                    temp[8] = double.Parse(dataSDCM[j][7]);//a
                    temp[9] = double.Parse(dataSDCM[j][8]);//b
                    ANSIParam[ANSIIndex] = temp;
                    ANSIIndex++;
                }
                else if (dataSDCM[j][0].Substring(0, 3) == "IEC")
                {
                    temp = new double[10];
                    IECTc[IECIndex] = int.Parse(dataSDCM[j][0].Substring(5, 4));
                    temp[0] = double.Parse(dataSDCM[j][9]);//x1
                    temp[1] = double.Parse(dataSDCM[j][10]);//y1
                    temp[2] = double.Parse(dataSDCM[j][3]);//g11
                    temp[3] = double.Parse(dataSDCM[j][4]);//g12
                    temp[4] = double.Parse(dataSDCM[j][5]);//g13
                    temp[5] = double.Parse(dataSDCM[j][6]);//angle
                    temp[6] = double.Parse(dataSDCM[j][1]);//x
                    temp[7] = double.Parse(dataSDCM[j][2]);//y
                    temp[8] = double.Parse(dataSDCM[j][7]);//a
                    temp[9] = double.Parse(dataSDCM[j][8]);//b
                    IECParam[IECIndex] = temp;
                    IECIndex++;
                }
            }
        }

        private void drawSDCM(ZedGraphControl zed, string fileName, int i_indexSDCM, int rankLo, int rankHi)
        {
            #region 初始化

            zed.GraphPane.Chart.Fill = new ZedGraph.Fill(Color.White, Color.LightGoldenrodYellow, 45.0f);// 填充背景色
            zed.IsShowPointValues = true;// 点设置
            zed.PointDateFormat = "#0.0000";
            zed.GraphPane.Title.Text = "";// 标题设置
            // X轴设置
            zed.GraphPane.XAxis.Title.Text = "";
            zed.GraphPane.XAxis.Scale.Min = 0;
            zed.GraphPane.XAxis.Scale.Max = 0.9;
            zed.GraphPane.XAxis.MajorGrid.IsVisible = false;
            // Y轴设置
            zed.GraphPane.YAxis.Title.Text = "";
            zed.GraphPane.YAxis.Scale.Min = 0;
            zed.GraphPane.YAxis.Scale.Max = 0.8;
            zed.GraphPane.YAxis.MajorGrid.IsVisible = false;
            zed.GraphPane.YAxis.MajorGrid.IsZeroLine = false;// Y=0不显示

            zed.IsShowContextMenu = false;// 设置右键功能选项

            zed.GraphPane.AxisChange();

            readSDCM(fileName);// 读取SDCM标准数据

            #endregion

            #region 选择标准

            int i = -1;
            int j = -1;

            if (sdcmIndex == 0)
            {
                i = 0;
            }
            else if (sdcmIndex == 1)
            {
                i = 1;
            }
            else if (sdcmIndex == 2)
            {
                i = 2;
            }
            else if (sdcmIndex == 3)
            {
                i = 3;
            }
            else if (sdcmIndex == 4)
            {
                i = 4;
            }
            else if (sdcmIndex == 5)
            {
                i = 5;
            }
            else if (sdcmIndex == 6)
            {
                j = 0;
            }
            else if (sdcmIndex == 7)
            {
                j = 1;
            }
            else if (sdcmIndex == 8)
            {
                j = 2;
            }
            else if (sdcmIndex == 9)
            {
                j = 3;
            }
            else if (sdcmIndex == 10)
            {
                j = 4;
            }
            else if (sdcmIndex == 11)
            {
                j = 5;
            }

            double angle = 0, x = 0, y = 0, a = 0, b = 0;

            if (i != -1)
            {
                angle = ANSIParam[i][5];
                x = ANSIParam[i][6];
                y = ANSIParam[i][7];
                a = ANSIParam[i][8];
                b = ANSIParam[i][9];
            }
            if (j != -1)
            {
                angle = ANSIParam[j][5];
                x = ANSIParam[j][6];
                y = ANSIParam[j][7];
                a = ANSIParam[j][8];
                b = ANSIParam[j][9];
            }

            #endregion

            #region 画图

            if (zed.GraphPane.CurveList.Count > 0)
            {
                zed.GraphPane.CurveList[0].Clear();
                zed.GraphPane.CurveList[1].Clear();
                zed.GraphPane.CurveList[2].Clear();
            }
            double x1, y1, x2, y2, r;
            angle = angle / 180 * Math.PI;

            PointPairList McAdamPoint1 = new ZedGraph.PointPairList();
            PointPairList McAdamPoint2 = new ZedGraph.PointPairList();
            PointPairList xyPoint = new ZedGraph.PointPairList();
            for (int k = 0; k < 165; k++)
            {
                r = -Math.PI + 0.04f * k;
                x1 = rankLo * a * Math.Sin(r) * Math.Cos(angle) - rankLo * b * Math.Sin(angle) * Math.Cos(r) + x;
                y1 = rankLo * a * Math.Sin(r) * Math.Sin(angle) + rankLo * b * Math.Cos(angle) * Math.Cos(r) + y;
                x2 = rankHi * a * Math.Sin(r) * Math.Cos(angle) - rankHi * b * Math.Sin(angle) * Math.Cos(r) + x;
                y2 = rankHi * a * Math.Sin(r) * Math.Sin(angle) + rankHi * b * Math.Cos(angle) * Math.Cos(r) + y;
                McAdamPoint1.Add(x1, y1);
                McAdamPoint2.Add(x2, y2);
            }
            LineItem McAdamLine1 = zed.GraphPane.AddCurve("", McAdamPoint1, Color.Green, SymbolType.None);
            LineItem McAdamLine2 = zed.GraphPane.AddCurve("", McAdamPoint2, Color.Green, SymbolType.None);

            zed.GraphPane.CurveList[0] = McAdamLine1;
            zed.GraphPane.CurveList[1] = McAdamLine2;

            xyPoint.Add(x, y);
            LineItem xyLine = zed.GraphPane.AddCurve("", xyPoint, Color.Brown, ZedGraph.SymbolType.Triangle);
            zed.GraphPane.CurveList[2] = xyLine;
            // 坐标变换
            zed.GraphPane.XAxis.Scale.Min = x - x * 0.1;
            zed.GraphPane.XAxis.Scale.Max = x + x * 0.1;
            zed.GraphPane.YAxis.Scale.Min = y - y * 0.1;
            zed.GraphPane.YAxis.Scale.Max = y + y * 0.1;

            pplSDCM.Clear();

            litSDCM = zed.GraphPane.AddCurve("", pplSDCM, Color.Red, SymbolType.XCross);
            litSDCM.Line.IsVisible = false;

            zed.Refresh();

            #endregion
        }

        private void pointSDCM(double x, double y)
        {
            pplSDCM.Clear();

            pplSDCM.Add(x, y);
            
            litSDCM = zedSDCM.GraphPane.AddCurve("", pplSDCM, Color.Red, SymbolType.XCross);
            litSDCM.Line.IsVisible = false;

            zedSDCM.Refresh();
        }

        public void SelectSDCM()
        {
            drawSDCM(zedSDCM, Application.StartupPath + "\\data\\SDCM.txt", sdcmIndex, rankLo, rankHi);
        }

        private void enableButton()
        {
            tlClear.Enabled = true;
            tlSave.Enabled = true;
            tlSetting.Enabled = true;
            tlMeasure.Enabled = true;
        }

        private void unableButton()
        {
            tlClear.Enabled = false;
            tlSave.Enabled = false;
            tlSetting.Enabled = false;
            tlMeasure.Enabled = false;
        }

        private void output()
        {
            //int[] dataCount = new int[dgvList.ColumnCount - 1];

            //for (int i = 0; i < dataCount.Length; i++)
            //{
            //    dataCount[i] = 1;
            //}

            //SaveFileDialog sfdOutput = new SaveFileDialog();

            //sfdOutput.Filter = "files (*.xls)|*.xls";
            //sfdOutput.FilterIndex = 0;
            //sfdOutput.Title = "保存为Excel文件";
            //sfdOutput.FileName = DateTime.Now.ToString("yyyyMMdd") + DateTime.Now.Hour.ToString("00") + DateTime.Now.Minute.ToString("00"); //默认保存文件名
            //if (sfdOutput.ShowDialog() == DialogResult.OK)
            //{
            //    ClassExportExcel classExportExcel = new ClassExportExcel();
            //    classExportExcel.StartThread(dgvList, information, dataCount, sfdOutput.FileName);
            //}

            SaveFileDialog sfdOutput = new SaveFileDialog();

            sfdOutput.Filter = "CSV (逗号分隔)(*.csv)|*.csv";
            sfdOutput.FilterIndex = 0;
            sfdOutput.Title = "另存为";
            sfdOutput.FileName = DateTime.Now.ToString("yyyyMMdd") + DateTime.Now.Hour.ToString("00") + DateTime.Now.Minute.ToString("00"); //默认保存文件名

            if (sfdOutput.ShowDialog() == DialogResult.OK)
            {
                using (StreamWriter sw = new StreamWriter(sfdOutput.FileName, false, Encoding.Default))
                {
                    StringBuilder sb = new StringBuilder();
                    //sb.Append("产品类型：").Append(",").Append(information[0]).Append("\r\n");
                    //sb.Append("厂    商：").Append(",").Append(information[1]).Append("\r\n");
                    //sb.Append("日    期：").Append(",").Append(information[2]).Append("\r\n");
                    //sb.Append("环境温度：").Append(",").Append(information[3]).Append("\r\n");
                    //sb.Append("环境湿度：").Append(",").Append(information[4]).Append("\r\n");
                    //sb.Append("测试人员：").Append(",").Append(information[5]).Append("\r\n").Append("\r\n");

                    for (int i = 0; i < dgvList.Columns.Count; i++)
                    {
                        if (i == dgvList.Columns.Count)
                        {
                            sb.Append(dgvList.Columns[i].HeaderText).Append("\r\n");
                        }
                        else
                        {
                            sb.Append(dgvList.Columns[i].HeaderText).Append(",");
                        }
                    }

                    for (int i = 0; i < dgvList.Rows.Count; i++)
                    {
                        for (int j = 0; j < dgvList.Columns.Count - 1; j++)
                        {
                            if (j == dgvList.Columns.Count)
                            {
                                sb.Append(dgvList[j, i].Value.ToString()).Append("\r\n");
                            }
                            else
                            {
                                sb.Append(dgvList[j, i].Value.ToString()).Append(",");
                            }
                        }
                    }

                    sw.WriteLine(sb.ToString());
                    sw.Close();
                }
            }
        }

        private void measure()
        {
            if (isMeasure)
            {
                classSourceMeter.Set(sourceMode, sptSource, voltSet, currSet);
                classSourceMeter.LightOn(sourceMode, sptSource);
                classSpectralMeter.Measure(param, 380d, 830d, ref result);
                Thread.Sleep(300);
                classSourceMeter.Measure(sourceMode, sptSource, ref voltCheck, ref currCheck);
                classSourceMeter.LightOff(sourceMode, sptSource);

                BeginInvoke(new dlgDisplay(display));

                isMeasure = false;

                BeginInvoke(new dlgShowButton(enableButton));
            }
        }

        private void display()
        {
            result.x += secondParam[1];
            result.y += secondParam[2];
            result.colorTemp += secondParam[3];

            chartRadiant.ChartGroups.ChartGroupsCollection[0].ChartData.SeriesList[0].PointData.Clear();

            for (int i = 0; i < result.waveleng.Length; i++)
            {
                chartRadiant.ChartGroups.ChartGroupsCollection[0].ChartData.SeriesList[0].X.Add(result.waveleng[i]);
                chartRadiant.ChartGroups.ChartGroupsCollection[0].ChartData.SeriesList[0].Y.Add(result.calcSpec[i] / result.calcSpec.Max() * 100);

                chartRadiant.ChartArea.AxisX.Max = 830;
                chartRadiant.ChartArea.AxisX.Min = 360;
            }

            pointCIE(result.x, result.y);
            pointSDCM(result.x, result.y);

            DataGridViewRow row = new DataGridViewRow();
            row.CreateCells(dgvList);

            row.Cells[0].Value = "N-" + index.ToString("#0000");
            row.Cells[1].Value = result.uWatt.ToString("#0.0");
            row.Cells[2].Value = result.lm.ToString("#0.0");
            row.Cells[3].Value = result.x.ToString("#0.0000");
            row.Cells[4].Value = result.y.ToString("#0.0000");
            row.Cells[5].Value = result.z.ToString("#0.0000");
            row.Cells[6].Value = result.u.ToString("#0.0000");
            row.Cells[7].Value = result.v1960.ToString("#0.0000");
            row.Cells[8].Value = result.v1976.ToString("#0.0000");
            row.Cells[9].Value = result.pwl.ToString("#0.00");
            row.Cells[10].Value = result.cwl.ToString("#0.00");
            row.Cells[11].Value = result.dwl.ToString("#0.00");
            row.Cells[12].Value = result.purity.ToString("#0.000");
            row.Cells[13].Value = result.halfWidth.ToString("#0.00");
            row.Cells[14].Value = result.colorTemp.ToString("#0");
            row.Cells[15].Value = result.ra.ToString("#0.0");
            row.Cells[16].Value = result.r[8].ToString("#0.0");

            dgvList.Rows.Add(row);

            index++;
        }

        private void clear()
        {
            chartRadiant.ChartGroups.ChartGroupsCollection[0].ChartData.SeriesList[0].PointData.Clear();

            pplCIE1931.Clear();
            pplSDCM.Clear();

            dgvList.Rows.Clear();

            index = 1;
        }

        #endregion

        #region 窗体事件

        private void frmR7_Load(object sender, EventArgs e)
        {
            drawCIE(zedCIE, Application.StartupPath + "\\data\\CIE1931.txt");
            drawSDCM(zedSDCM, Application.StartupPath + "\\data\\SDCM.txt", sdcmIndex, rankLo, rankHi);

            if (!sourceIsJoin)
            {
                MessageBox.Show("电源未连接！", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            if (!spectralIsJoin)
            {
                MessageBox.Show("光谱仪未连接！", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            clear();
        }

        private void frmR7_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (isMeasure)
            {
                MessageBox.Show("正在测试！", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                if (sourceIsJoin)
                {
                    classSourceMeter.LightOff(sourceMode, sptSource);
                }

                if (threadMeasure != null)
                {
                    if (threadMeasure.IsAlive)
                    {
                        threadMeasure.Abort();
                    }
                }
            }
        }

        #endregion

        #region 按钮事件

        private void tlClear_Click(object sender, EventArgs e)
        {
            clear();
        }

        private void tlSave_Click(object sender, EventArgs e)
        {
            output();
        }

        private void tlSetting_Click(object sender, EventArgs e)
        {
            frmRMeasSetting frm_RMeasSeting = new frmRMeasSetting();

            frm_RMeasSeting.Param = param;
            //frm_RMeasSeting.TimeSpace = timeSpace;
            frm_RMeasSeting.VoltSet = voltSet;
            frm_RMeasSeting.CurrMax = currSet;
            frm_RMeasSeting.IsR7 = isR7;

            frm_RMeasSeting.ShowDialog();

            if (frm_RMeasSeting.DialogResult == DialogResult.OK)
            {
                param = frm_RMeasSeting.Param;
                //timeSpace = frm_RMeasSeting.TimeSpace;
                voltSet = frm_RMeasSeting.VoltSet;
                currSet = frm_RMeasSeting.CurrMax;
            }
        }

        private void tlMeasure_Click(object sender, EventArgs e)
        {
            if (!sourceIsJoin)
            {
                MessageBox.Show("电源未连接！", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (!spectralIsJoin)
            {
                MessageBox.Show("光谱仪未连接！", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            //clear();

            threadMeasure = new Thread(measure);
            isMeasure = true;
            unableButton();
            threadMeasure.Start();
        }

        #endregion
    }
}
